#pragma once
#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<mutex>
#include<unordered_map>
#include<boost/algorithm/string.hpp>
#include"../cppjieba/include/cppjieba/Jieba.hpp"

 
namespace ns_util
{
    class FileUtil
    {
        public:
        //读取文件内容
        static bool ReadFile(const std::string &file_path/*输入*/,std::string *out/*输入*/)
        {
            std::ifstream in(file_path,std::ios::in);//打开文件
            if(!in.is_open())//打开失败
            {
              std::cerr<<"open file"<<file_path<<"error"<<std::endl;
              return false;  
            }
            std::string line;//字符类对象
            while (std::getline(in,line))//读取一行 ，循环读取
            {
                *out +=line;
            }
            in.close();
            return true;
        }
    };
    class StringUtil//将字符串按分隔符切分
    {
        public:
        static void Split(const std::string &target/*等待切分字符串*/,std::vector<std::string>*out,const std::string &sep/*分隔符*/)
        {
            boost::split(*out,target,boost::is_any_of(sep),boost::token_compress_on);
        }
    };

    const char* const DICT_PATH = "./dict/jieba.dict.utf8";//DICT 路径
    const char* const HMM_PATH = "./dict/hmm_model.utf8";//hmm 路径
    const char* const USER_DICT_PATH = "./dict/user/dict.utf8";//user 路径
     const char* const IDF_PATH = "./dict/idf.utf8";//idf 路径
      const char* const STOP_WORD_PATH = "./dict/stop_words.utf8";//stop_words//路径
      
      class JiebaUtil
      {
            private:
            cppjieba::Jieba jieba;
            std::unordered_map<std::string,bool> stop_words;
            private:
            JiebaUtil():jieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH)//文件路径
            {}
            JiebaUtil(const JiebaUtil&) =delete;//禁止拷贝
            static JiebaUtil *instance;
            public:
            static JiebaUtil *get_instance()//获取实例
            {
                static std::mutex mtx;//互斥锁
                if(instance == nullptr)
                {
                    mtx.lock();
                    if(instance == nullptr)
                    {
                        instance == new JiebaUtil();
                        instance->initJiebaUtil();
                    }
                    mtx.unlock();
                }
                return instance;
            }
        
            void initJiebaUtil()//初始化jiebaUtil
            {
                std::ifstream in(STOP_WORD_PATH);
                if(!in.is_open())
                {
                    //日志
                    return;
                }
                std::string line;
                while (std::getline(in,line))
                {
                    stop_words.insert({line,true});
                }
                in.close();
                
            }
            void CutStringHelper(const std::string &src,std::vector<std::string> *out)
            {
                jieba.CutForSearch(src,*out);
                for(auto iter = out->begin();iter!=out->end();)
                {
                    auto it = stop_words.find(*iter);
                    if(it!=stop_words.end())
                    {
                        iter == out->erase(iter);
                    }
                    else
                    {
                        iter++;
                    }
                }
            }
            public:
            static void CutString(const std::string &src,std::vector<std::string>*out)
            {
                ns_util::JiebaUtil::get_instance()->CutStringHelper(src,out);
            }
        };
    JiebaUtil *JiebaUtil::instance = nullptr;
}